# -*- coding: utf-8 -*-
"""
===============================
@Author     : Zuo WenTao
@Time       : 2024/11/21 14:22
@Description:
@Change     :
@File       : TransitiveRun.py
===============================
"""
import sys
import platform


if platform.system().lower() == 'linux':
    sys.path.append("/home/zuo/26_DocumentDelivery/")
import queue
import time

from queue import Queue

from loguru import logger
from datetime import datetime, timedelta
from concurrent.futures import ThreadPoolExecutor, as_completed

from Api.EsClient import ES_INDEX, es_client
from Api.mongo_client import mongo_client2
from Task.DocumentDelivery import DocumentDelivery, SpiderDoi
from Api.Google_Title import Google_Title_

Q = Queue()
table = "DocumentDeliveryTask"


def get_previous_and_next_day(date_str):
    current_date = datetime.strptime(date_str, "%Y-%m-%d %H:%M:%S")

    previous_day_midnight = current_date - timedelta(days=1, hours=current_date.hour, minutes=current_date.minute, seconds=current_date.second)

    next_day_midnight = current_date + timedelta(days=0, hours=current_date.hour, minutes=current_date.minute, seconds=current_date.second) - timedelta(seconds=1)

    previous_day_midnight_str = previous_day_midnight.strftime("%Y-%m-%d %H:%M:%S")
    next_day_midnight_str = next_day_midnight.strftime("%Y-%m-%d %H:%M:%S")

    return previous_day_midnight_str, next_day_midnight_str


def update_status(send_bool, send_massage, email, title, task_id, error_num=0):
    if not send_bool:
        status = -1 if send_massage == "未搜索到文献" else (0 if error_num <= 5 else -2)
    else:
        status = 2

    update_data = {
        "error_msg": send_massage if error_num <= 5 else "文献多次传递失败, 不进行处理",
        "status": status,
        "title": title,
        "email": email,
        "error_num": error_num + 1 if not send_bool else 0,
    }

    insert_status, insert_res = mongo_client2.update_document(table, {"task_id": task_id}, {"$set": update_data}, upsert=True)
    return insert_status, insert_res


def handle_es_result(res, doi):
    if res:
        for item in res:
            if item["title"] == doi:
                search_doi = item["doi"]
                return search_doi
    return None


def transitive_handler():
    while not Q.empty():
        try:
            doi, task_id, error_num = Q.get()
            bool_doi = doi.startswith("10.")
            if not bool_doi: continue
            # if not bool_doi and error_num <= 5:
            #     search_doi = ""
            #     try:
            #         res = es_client.msearch_documents(
            #             index_name=ES_INDEX,
            #             queries=[doi],
            #             search_type="title",
            #             reflection_type="text",
            #         )
            #         search_doi = handle_es_result(res, doi)
            #
            #         if not search_doi:
            #             res = Google_Title_.main(doi)
            #             if res and res.get("finalHref"):
            #                 search_doi = SpiderDoi(url=res["finalHref"]).run()
            #     except Exception as e:
            #         print(f"Error occurred while processing DOI {doi}: {e}")
            #
            #     if search_doi and search_doi.startswith("10."):
            #         mongo_client2.update_document(table, {"task_id": task_id}, {"$set": {"doi": search_doi, "title": doi}})
            #         doi = search_doi
            #         bool_doi = True

            logger.debug(f"正在处理doi: {doi}, task_id: {task_id}")

            send_bool, send_massage, email, title = DocumentDelivery().run(doi) if bool_doi else DocumentDelivery().run(doi, type="title")

            if any([error_msg in send_massage for error_msg in ["验证码多次失败", "IP被封禁"]]):
                logger.error(f"{send_massage}，task_id: {task_id}")
                continue

            insert_status, insert_res = update_status(send_bool, send_massage, email, title, task_id, error_num)

            assert insert_status, "插入失败！"
            if not insert_status:
                logger.error(f"{task_id} ---- 入库失败！")
            logger.success(f'DOI：{doi} 任务传递成功 ，task_id:{task_id}') if send_bool else logger.error(f'DOI：{doi}任务传递失败 ，task_id:{task_id}，error_msg:{send_massage}')

        except Exception as e:
            logger.error(f"出现错误: {e}")
            insert_status, insert_res = update_status(False, str(e), "", "", task_id, error_num)
            continue


if __name__ == '__main__':
    # query = {"status": 0}
    query = {"task_id": "f0b9c3e72e5a7f3c9db95d45c350fcf9"}
    projection = {"_id": 0, "doi": 1, "task_id": 1, "error_num": 1}
    # while True:
    date_str = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    previous_day_midnight, next_day_midnight = get_previous_and_next_day(date_str)
    query = {"status": 0, "create_date": {"$gte": previous_day_midnight, "$lt": next_day_midnight}}
    query = {"error_msg": "未搜索到文献"}
    document_bool, document = mongo_client2.find_document(table, query=query, projection=projection, Type=2)
    if not document_bool:
        time.sleep(20)
        # continue
    for item in document:
        Q.put([item["doi"], item["task_id"], item.get("error_num", 0)])

    logger.debug(f"本次待文献传递的队列长度为: {Q.qsize()}")

    # transitive_handler()

    task_list = []
    max_work_num = 10
    with ThreadPoolExecutor(max_workers=max_work_num) as executor:
        for i in range(max_work_num):
            task_list.append(executor.submit(transitive_handler))

    as_completed(task_list)

    time.sleep(10)
# nohup python3 -u /home/zuo/26_DocumentDelivery/Task/TransitiveRun.py > /home/zuo/26_DocumentDelivery/Task/TransitiveRun.log 2>&1 &
